package com.jsu.clubmanagementsystem.service.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsu.clubmanagementsystem.common.ErrorCode;
import com.jsu.clubmanagementsystem.common.PageQueryRequest;
import com.jsu.clubmanagementsystem.constant.UserConstant;
import com.jsu.clubmanagementsystem.exception.BusinessException;
import com.jsu.clubmanagementsystem.model.dto.user.*;
import com.jsu.clubmanagementsystem.model.entity.User;
import com.jsu.clubmanagementsystem.model.vo.user.UserListsVO;
import com.jsu.clubmanagementsystem.mapper.UserMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Random;

/**
* @author 24753
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2025-05-13 17:29:48
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    /**
     * 管理员注册密钥
     */
    @Value("${secret-key.admin}")
    private String ADMIN_REGISTER_SECRET_KEY;

    /**
     * 用户注册
     *
     * @param registerRequest
     * @return
     */
    @Override
    public boolean userRegister(UserRegisterRequest registerRequest, boolean isAdmin) {
        // 验证数据
        userRegisterValidation(registerRequest);

        // 插入数据
        User user = new User();
        String userAccount = registerRequest.getUserAccount();
        user.setUserAccount(userAccount);
        user.setUserPassword(registerRequest.getUserPassword());
        user.setUserName(UserConstant.USER_DEFAULT_NAME + userAccount);
        if (isAdmin) {
            user.setUserRole(UserConstant.USER_ROLE_ADMIN);
        } else {
            user.setUserRole(UserConstant.USER_ROLE_USER);
        }
        return this.save(user);
    }

    /**
     * 管理员注册
     *
     * @param registerRequest
     * @return
     */
    @Override
    public boolean adminRegister(AdminRegisterRequest registerRequest) {
        if (registerRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }

        // 密钥验证
        String secretKey = registerRequest.getSecretKey();
        if (secretKey == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "密钥为空");
        } else if (!secretKey.equals(ADMIN_REGISTER_SECRET_KEY)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "密钥错误");
        }

        UserRegisterRequest userRegisterRequest = new UserRegisterRequest();
        BeanUtils.copyProperties(registerRequest, userRegisterRequest);
        return this.userRegister(userRegisterRequest, true);
    }

    /**
     * 用户登录
     *
     * @param loginRequest
     * @param request
     * @return
     */
    @Override
    public User userLogin(UserLoginRequest loginRequest, HttpServletRequest request) {
        userLoginValidation(loginRequest);

        // 账号是否存在
        String userAccount = loginRequest.getUserAccount();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        if (this.count(queryWrapper) < 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "账号不存在");
        }

        // 密码验证
        queryWrapper.eq("userPassword", loginRequest.getUserPassword());
        User user = this.getOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "密码错误");
        }

        // session管理登录状态
        HttpSession session = request.getSession();
        session.setAttribute(UserConstant.USER_LOGIN_STATE, user);
        return user;
    }

    /**
     * 用户登出
     *
     * @param request
     * @return
     */
    @Override
    public boolean userLogout(HttpServletRequest request) {
        HttpSession session = request.getSession();
        Object userObj = session.getAttribute(UserConstant.USER_LOGIN_STATE);
        if (userObj == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录，无法登出");
        }

        session.setAttribute(UserConstant.USER_LOGIN_STATE, null);
        return true;
    }

    /**
     * 更新登录用户信息之后同步更新session中的信息
     *
     * @param id
     * @param request
     * @return
     */
    @Override
    public void updateLoginUser(long id, HttpServletRequest request) {
        HttpSession session = request.getSession();
        User newUser = this.getById(id);
        session.setAttribute(UserConstant.USER_LOGIN_STATE, newUser);
    }

    /**
     * 获取当前登录用户信息
     *
     * @param request
     * @return
     */
    @Override
    public User getLoginUser(HttpServletRequest request) {
        if (request == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }

        HttpSession session = request.getSession();
        Object userObj = session.getAttribute(UserConstant.USER_LOGIN_STATE);
        if (userObj == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录，无法获取信息");
        }

        User user = (User) userObj;
        return this.getById(user.getId());
    }

    /**
     * 创建用户
     *
     * @param addRequest
     * @return
     */
    @Override
    public Long addUser(UserAddRequest addRequest) {
        addUserValidation(addRequest);

        User user = new User();
        BeanUtils.copyProperties(addRequest, user);
        user.setUserRole(UserConstant.USER_ROLE_USER);
        if (!this.save(user)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "创建用户失败");
        }
        return user.getId();
    }

    /**
     * 修改用户信息
     *
     * @param updateRequest
     * @return
     */
    @Override
    public boolean updateUser(UserUpdateRequest updateRequest) {
        // 存在性验证
        Long id = updateRequest.getId();
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "用户不存在");
        }
        User newUser = new User();
        newUser.setId(user.getId());

        // 账号密码验证
        String originUserPassword = updateRequest.getOriginUserPassword();
        if (StringUtils.isNotBlank(originUserPassword) && !originUserPassword.equals(user.getUserPassword())) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "原密码错误");
        }
        String userAccount = updateRequest.getUserAccount();
        if (StringUtils.isNotBlank(userAccount) && !userAccount.equals(user.getUserAccount())) {
            userAccountValidation(userAccount);
            newUser.setUserAccount(userAccount);
            user.setUserAccount(userAccount);
        }
        String newUserPassword = updateRequest.getNewUserPassword();
        String checkedNewUserPassword = updateRequest.getCheckedNewUserPassword();
        if (!StringUtils.isAllBlank(newUserPassword, checkedNewUserPassword)) {
            userPasswordValidation(newUserPassword, checkedNewUserPassword);
            newUser.setUserPassword(newUserPassword);
            user.setUserPassword(newUserPassword);
        }

        // 个人信息验证
        String userName = updateRequest.getUserName();
        if (StringUtils.isNotBlank(userName)) {
            newUser.setUserName(userName);
            user.setUserName(userName);
        }
        String userAvatar = updateRequest.getUserAvatar();
        if (StringUtils.isNotBlank(userAvatar)) {
            newUser.setUserAvatar(userAvatar);
            user.setUserAvatar(userAvatar);
        }
        String phoneNumber = updateRequest.getPhoneNumber();
        if (StringUtils.isNotBlank(phoneNumber)) {
            newUser.setPhoneNumber(phoneNumber);
            user.setPhoneNumber(phoneNumber);
        }
        String major = updateRequest.getMajor();
        if (StringUtils.isNotBlank(major)) {
            newUser.setMajor(major);
            user.setMajor(major);
        }
        String grade = updateRequest.getGrade();
        if (StringUtils.isNotBlank(grade)) {
            newUser.setGrade(grade);
            user.setGrade(grade);
        }
        String userClass = updateRequest.getUserClass();
        if (StringUtils.isNotBlank(userClass)) {
            newUser.setUserClass(userClass);
            user.setUserClass(userClass);
        }

        userInfoValidation(newUser);
        return this.updateById(user);
    }

    /**
     * 用户注册/修改账号密码 参数验证
     *
     * @param registerRequest
     */
    private void userRegisterValidation(UserRegisterRequest registerRequest) {
        if (registerRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }

        // 参数验证
        String userAccount = registerRequest.getUserAccount();
        String userPassword = registerRequest.getUserPassword();
        String checkPassword = registerRequest.getCheckPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号/密码/确认密码为空");
        }
        userAccountValidation(userAccount);
        userPasswordValidation(userPassword, checkPassword);
    }

    /**
     * 用户登录参数验证
     *
     * @param loginRequest
     */
    private void userLoginValidation(UserLoginRequest loginRequest) {
        if (loginRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }

        String userAccount = loginRequest.getUserAccount();
        String userPassword = loginRequest.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号/密码为空");
        }
    }

    /**
     * 针对addUser方法的参数验证方法
     *
     * @param addRequest
     */
    private void addUserValidation(UserAddRequest addRequest) {
        // 账号密码验证
        UserRegisterRequest userRegisterRequest = new UserRegisterRequest();
        BeanUtils.copyProperties(addRequest, userRegisterRequest);
        userRegisterValidation(userRegisterRequest);

        // 个人信息验证
        User user = new User();
        BeanUtils.copyProperties(addRequest, user);
        user.setUserRole(UserConstant.USER_ROLE_USER);
        userInfoValidation(user);
    }

    /**
     * 用户账号验证
     *
     * @param userAccount
     */
    private void userAccountValidation(String userAccount) {
        if (StringUtils.isBlank(userAccount)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号为空");
        }
        if (userAccount.length() > 24) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号过长");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        if (this.count(queryWrapper) > 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "已存在此账号");
        }
    }

    /**
     * 用户密码验证
     *
     * @param userPassword
     * @param checkPassword
     */
    private void userPasswordValidation(String userPassword, String checkPassword) {
        if (StringUtils.isAnyBlank(userPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "密码为空");
        }
        if (userPassword.length() > 16) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "密码过长");
        } else if (userPassword.length() < 6) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "密码过短");
        }
        if (!userPassword.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "两次输入密码不一致");
        }
    }

    /**
     * 用户个人信息验证
     *
     * @param user
     */
    private void userInfoValidation(User user) {
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }

        String phoneNumber = user.getPhoneNumber();
        if (StringUtils.isNotBlank(phoneNumber) && phoneNumber.length() != 11) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "手机号码格式错误");
        }

        String userName = user.getUserName();
        if (StringUtils.isNotBlank(userName) && userName.length() > 32) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "用户名过长");
        }
        String userAvatar = user.getUserAvatar();
        if (StringUtils.isNotBlank(userAvatar) && userAvatar.length() > 128) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "用户头像地址过长");
        }

        String major = user.getMajor();
        if (StringUtils.isNotBlank(major) && major.length() > 50) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "用户头像地址过长");
        }
        String grade = user.getGrade();
        if (StringUtils.isNotBlank(grade) && grade.length() > 10) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "用户头像地址过长");
        }
        String userClass = user.getUserClass();
        if (StringUtils.isNotBlank(userClass) && userClass.length() > 20) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "用户头像地址过长");
        }
    }

    /**
     * 用户是否存在
     *
     * @param userId
     * @return
     */
    @Override
    public boolean isExist(Long userId) {
        if (userId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        return this.getById(userId) != null;
    }

    /**
     * 判断当前登录用户是否为管理员
     *
     * @param request
     * @return
     */
    @Override
    public boolean isAdmin(HttpServletRequest request) {
        User loginUser = getLoginUser(request);
        return loginUser.getUserRole().equals(UserConstant.USER_ROLE_ADMIN);
    }

    /**
     * 获取用户查询对象
     *
     * @param queryRequest
     * @return
     */
    @Override
    public QueryWrapper<User> getQueryWrapper(UserQueryRequest queryRequest) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (queryRequest == null) {
            return queryWrapper;
        }

        Long id = queryRequest.getId();
        String userAccount = queryRequest.getUserAccount();
        String userName = queryRequest.getUserName();
        String major = queryRequest.getMajor();
        String grade = queryRequest.getGrade();
        String userRole = queryRequest.getUserRole();

        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.like(StringUtils.isNotBlank(userAccount), "userAccount", userAccount);
        queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
        queryWrapper.like(StringUtils.isNotBlank(major), "major", major);
        queryWrapper.like(StringUtils.isNotBlank(grade), "grade", grade);
        queryWrapper.like(StringUtils.isNotBlank(userRole), "userRole", userRole);
        return queryWrapper;
    }

    @Override
    public Page<UserListsVO> getAllUser(PageQueryRequest page) {
        Page<User> iPage=new Page<>(page.getCurrent(), page.getPageSize());
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        if(page.getQuery()!=null){
            queryWrapper.like("userName",page.getQuery());
        }
        List<UserListsVO> list = this.baseMapper.selectLists(iPage, queryWrapper)
                .stream().map(user -> {
                    UserListsVO userListsVO = new UserListsVO();
                    BeanUtils.copyProperties(user, userListsVO);
                    return userListsVO;
                }).toList();
        return new Page<UserListsVO>(page.getCurrent(), page.getPageSize()).setRecords(list).setTotal(iPage.getTotal());
    }



    @Override
    @Transactional
    public boolean removeUser(Long userId) {
        return this.baseMapper.deleteById(userId)!=0;
    }

    @Override
    public User addUsers(UserAddRequest addRequest) {
        User user=new User();
        addRequest.setUserAccount(makeUserAccount());
        BeanUtils.copyProperties(addRequest,user);
        log.error("用户信息：{}", user);
        if(!this.save(user)){
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加用户失败");
        }
        return user;
    }

    private String makeUserAccount(){
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            sb.append(random.nextInt(10));
        }
        log.error("生成用户账号：{}", sb.toString());
        return sb.toString();
    }
}




